﻿using RQX.Common.Core.Config;
using RQX.Common.Core.Db.Sqlite;
using RQX.Common.Core.Extension;
using RQX.Common.Core.Hardware.Com;
using RQX.Common.Core.Model;
using RQX.DataCollection.Test.Config;
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace RQX.DataCollection.Test.Com
{
    public partial class ComForm : Form
    {
        #region Init
        private ComConfig config;
        private MyCom _myCom = null;

        public ComForm()
        {
            InitializeComponent();
        }
        /// <summary>
        /// 界面初始化
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ComForm_Load(object sender, EventArgs e)
        {
            BindConfigToForm();
            // TODO 后续功能完善
            ckb_send_Circle.Enabled = false;
            ckb_send_File.Enabled = false;
            txt_send_CircleTime.Enabled = false;
            ckb_recv_AutoSave.Enabled = false;
            btn_recv_Save.Enabled = false;
        }

        private void BindConfigToForm()
        {
            config = ConfigUtils.GetConfigurationRoot().GetSection("COM").BuildClass<ComConfig>();
            txt_send_CircleTime.Text = config.Send_Circle_Time;
            ckb_recv_AutoSave.Checked = config.Recv_AutoSave;
            ckb_recv_Hex.Checked = config.Recv_Hex;
            ckb_recv_NewLine.Checked = config.Recv_NewLine;
            ckb_recv_Pause.Checked = config.Recv_Stop;
            ckb_send_AutoClean.Checked = config.Send_AutoClean;
            ckb_send_Circle.Checked = config.Send_Circle;
            ckb_send_File.Checked = config.Send_File;
            ckb_send_Hex.Checked = config.Send_Hex;
            ckb_DTR.Checked = config.DTR;
            ckb_RTS.Checked = config.RTS;
            BindListItemToDDL(ddl_PortName, ComUtils.GetComList(), initText: config.PortName);
            BindListItemToDDL(ddl_BaudRate, ComUtils.GetBaudRateList(), initValue: config.BaudRate);
            BindListItemToDDL(ddl_Parity, ComUtils.GetParityList(), initText:config.Parity.ToString());
            BindListItemToDDL(ddl_DataBits, ComUtils.GetDataBitsList(), initValue: config.DataBits);
            BindListItemToDDL(ddl_StopBits, ComUtils.GetStopBitsList(), initText: config.StopBits.ToString());
        }
        private void SaveFormToConfig()
        {
            config.Send_Circle_Time = txt_send_CircleTime.Text;
            config.Recv_AutoSave = ckb_recv_AutoSave.Checked;
            config.Recv_Hex = ckb_recv_Hex.Checked;
            config.Recv_NewLine = ckb_recv_NewLine.Checked;
            config.Recv_Stop = ckb_recv_Pause.Checked;
            config.Send_AutoClean = ckb_send_AutoClean.Checked;
            config.Send_Circle = ckb_send_Circle.Checked;
            config.Send_File = ckb_send_File.Checked;
            config.Send_Hex = ckb_send_Hex.Checked;
            config.DTR = ckb_DTR.Checked;
            config.RTS = ckb_RTS.Checked;
            config.PortName = (ddl_PortName.SelectedItem as ListItem).Text;
            config.BaudRate = (ddl_BaudRate.SelectedItem as ListItem).Value.ToInt();
            Enum.TryParse( (ddl_Parity.SelectedItem as ListItem).Text,out Parity parity);
            config.Parity = parity;
            config.DataBits = (ddl_DataBits.SelectedItem as ListItem).Value.ToInt();
            Enum.TryParse( (ddl_StopBits.SelectedItem as ListItem).Text,out StopBits stopBits);
            config.StopBits = stopBits;
            config.SaveConfig();
        }
        #endregion

        #region 事件
        /// <summary>
        /// 连接/断开连接
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Connect_Click(object sender, EventArgs e)
        {
            if (_myCom == null)
            {
                var portName = ddl_PortName.Text.Trim();
                if (portName.IsNullOrEmpty()) 
                {
                    ShowMsg("请选择串口号");
                }
                else
                {
                    var baudRate = (ddl_BaudRate.SelectedItem as ListItem).Value;
                    var dataBits = (ddl_DataBits.SelectedItem as ListItem).Value;
                    Enum.TryParse((ddl_Parity.SelectedItem as ListItem).Text, out Parity parity);
                    Enum.TryParse((ddl_StopBits.SelectedItem as ListItem).Text, out StopBits stopBits);
                    var dtr = ckb_DTR.Checked;
                    var rts = ckb_RTS.Checked;
                    _myCom = new MyCom(baudRate.ToInt(), portName, dataBits.ToInt(), stopBits, parity, dtr, rts);
                    _myCom.BindRecvedHandler(AppendRecvText);
                    try
                    {
                        _myCom.Open();
                        SaveFormToConfig();
                    }
                    catch (Exception ex)
                    {
                        ShowMsg($"串口打开失败！{ex}");
                        _myCom = null;
                        return;
                    }
                    ChangeConnectBtn(true);
                }
            }
            else
            {
                _myCom.Close();
                _myCom = null;
                ChangeConnectBtn(false);
            }
        }
        /// <summary>
        /// 清除接收区
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_recv_Clean_Click(object sender, EventArgs e)
        {
            txt_Recv.Text = "";
        }
        /// <summary>
        /// 发送
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Send_Click(object sender, EventArgs e)
        {
            if(_myCom == null || !_myCom.IsOpen())
            {
                ShowMsg("请先打开串口连接！");
                return;
            }
            var sendStr = txt_Send.Text;
            byte[] buffer;
            if (ckb_send_Hex.Checked)
            {
                buffer = sendStr.HexStringToByte();
            }
            else
            {
                buffer = sendStr.ToByte(Encoding.Default);
            }
            _myCom.Send(buffer);
            if (ckb_send_AutoClean.Checked)
            {
                txt_Send.Text = "";
            }
        }
        #endregion

        #region 私有函数

        private void ChangeConnectBtn(bool isConnected)
        {
            if (isConnected)//已连接
            {
                btn_Connect.Text = "断 开";
                btn_Connect.ForeColor = Color.Black;
            }
            else
            {
                btn_Connect.Text = "连 接";
                btn_Connect.ForeColor = Color.Red;
            }
        }


        /// <summary>
        /// 追加到输出区
        /// </summary>
        /// <param name="buffer"></param>
        private void AppendRecvText(byte[] buffer)
        {
            string line;
            if (ckb_recv_Pause.Checked) return;//暂停显示接收区
            if (ckb_recv_Hex.Checked)//16进制显示
            {
                line = buffer.ToHex(" ");
            }
            else
            {
                line = buffer.ToString(Encoding.Default);
            }
            if (ckb_recv_NewLine.Checked)//换行
            {
                line = $"{line}\n";
            }
            txt_Recv.Text += line;
        }

        private void ShowMsg(string msg)
        {
            MessageBox.Show(msg);
        }

        private void BindListItemToDDL(ComboBox comboBox, List<ListItem> list, int? initValue = null, string initText = null)
        {
            comboBox.DataSource = list;
            comboBox.ValueMember = "Value";
            comboBox.DisplayMember = "Text";
            if (initValue.HasValue)
            {
                var items = comboBox.Items.OfType<ListItem>().Where(k => k.Value.Equals(initValue.Value));
                if (items.Count() > 0)
                {
                    comboBox.SelectedIndex = comboBox.Items.IndexOf(items.FirstOrDefault());
                }
            }
            else if (initText.IsNotNullOrEmpty())
            {
                var items = comboBox.Items.OfType<ListItem>().Where(k => k.Text.Equals(initText));
                if (items.Count() > 0)
                {
                    comboBox.SelectedIndex = comboBox.Items.IndexOf(items.FirstOrDefault());
                }
            }
        }

        #endregion

       
    }
}
